import logging
from datetime import datetime
from common.timeutil import get_interval_end_pair
from common.es_core.user_filter import UserFilter
from common.es_core.report_creator import ReportCreator, UserReportCreator
from common.es_core.es_interface import es_search_interface
from common.mg_core.mg import get_report_template, insert_or_update, get_report
from common.account import db as account_db
from event_rule.cp.user_event_rule.active_user_analysis import ACTIVE_USER_ANALYSIS_CONFIG

_LOGGER = logging.getLogger(__name__)


def active_user_analysis_handler(interval_type, base_time, last_window, event_name, event_rule, index):
    start_time, end_time = get_interval_end_pair(interval_type, base_time, last_window)
    collection = '_'.join(['user', event_name, 'report'])
    user_analysis_report = ReportCreator.create_report(start_time=start_time, end_time=end_time, event_rule=event_rule,
                                                       index=index, to_group=True)
    user_id_list = [user_report['_user_id'] for user_report in user_analysis_report['list']]
    users, _ = account_db.list_user(index, {'user_id__in': user_id_list}, disable_paginate=True)
    user_dct = {str(user['user_id']): user for user in users}
    for user_report in user_analysis_report['list']:
        report_id = '-'.join([str(start_time).split(' ')[0], interval_type.value, str(user_report['_user_id'])])
        report_template = get_report_template(start_time, interval_type, custom_report_id=report_id)
        user = user_dct.get(str(user_report['_user_id']), {})
        user_report['chn'] = user.get('channel', '未知')
        user_report['registered_at'] = str(user.get('registered_at', '未知'))
        report_template.update(user_report)
        insert_or_update(report_template, database=index, collection=collection)


def recharge_stage_analysis_handler(interval_type, base_time, last_window, event_name, event_rule, index):
    start_time, end_time = get_interval_end_pair(interval_type, base_time, last_window)
    recharge_stages = ['NoRecharge', (0, 1), (1, 10), (10, 100), (100, 1000), (1000, 5000),
                       (5000, 10000), (10000, 50000), (50000, '无上限'), 'ALL']
    for recharge_stage in recharge_stages:
        user_filter = UserFilter()
        if recharge_stage == 'ALL':
            _id = '-'.join(['all', str(start_time).split(' ')[0]])
            stage, key = 'all', '汇总'
        elif recharge_stage == 'NoRecharge':
            user_filter.stage_filter(
                None, 'recharge_price', 'sum', start_time, end_time, None, 0
            )
            _id = '-'.join(['0', str(start_time).split(' ')[0]])
            stage, key = 'others', '未充值'
        else:
            user_filter.stage_filter(
                'recharge', 'recharge_price', 'sum', start_time, end_time, recharge_stage[0], recharge_stage[1]
            )
            _id = '-'.join(['-'.join([str(recharge_stage[0]), str(recharge_stage[1])]), str(start_time).split(' ')[0]])
            stage, key = str(recharge_stage[0]), '-'.join([str(recharge_stage[0]), str(recharge_stage[1])])
        user_pool = user_filter.get_user_pool()
        report_template = get_report_template(start_time, interval_type, custom_report_id=_id)
        report_template.update(
            UserReportCreator.create_user_report(start_time=start_time, end_time=end_time, event_rule=event_rule,
                                                 index=index, user_pool=user_pool)
        )
        report_template.update(dict(key=key, recharge_stage=stage))
        collection = '_'.join(['user', event_name, 'report'])
        insert_or_update(report_template, database=index, collection=collection)


def _get_user_pay_ability_report_dynamic_argument_dct(index, start_time, end_time, recharge_stage):
    # 充值用户
    user_filter = UserFilter(merchant_name=index)
    if recharge_stage[0] is not None and recharge_stage[1] is not None:
        user_filter.stage_filter('recharge', 'recharge_price', 'sum', start_time, end_time,
                                 recharge_stage[0], recharge_stage[1])
    elif recharge_stage[1] is not None:
        user_filter.stage_filter(['recharge', 'active'], 'recharge_price', 'sum', start_time, end_time,
                                 recharge_stage[0], recharge_stage[1])
    else:
        user_filter.event_user_filter('recharge', start_time, end_time)
    recharge_user_pool = user_filter.get_user_pool()
    # 充值且参与用户
    user_filter = UserFilter(recharge_user_pool, merchant_name=index)
    user_filter.event_user_filter(['cp_lottery', 'cp_game'], start_time, end_time)
    recharge_bet_user_pool = user_filter.get_user_pool()
    # 充值且中奖用户
    user_filter = UserFilter(recharge_user_pool, merchant_name=index)
    user_filter.event_user_filter(['cp_lottery', 'cp_game'], start_time, end_time, custom_filter=[
        {"bool": {"should": [
            {"range": {"cp_game_win": {"gt": 0}}},
            {"range": {"cp_lottery_win": {"gt": 0}}}
        ]}}])
    recharge_win_user_pool = user_filter.get_user_pool()
    # 充值且盈利用户
    user_filter = UserFilter(recharge_user_pool, merchant_name=index)
    user_filter.stage_filter(['cp_game', 'cp_lottery'], ['cp_lottery_profit', 'cp_game_profit'],
                             'sum', start_time, end_time, 0)
    recharge_profit_user_pool = user_filter.get_user_pool()
    # 充值且亏损用户
    user_filter = UserFilter(recharge_user_pool, merchant_name=index)
    user_filter.stage_filter(['cp_game', 'cp_lottery'], ['cp_lottery_profit', 'cp_game_profit'],
                             'sum', start_time, end_time, None, 0)
    recharge_lose_user_pool = user_filter.get_user_pool()
    dynamic_target_users_dct = dict(
        recharge_users=recharge_user_pool,
        recharge_bet_users=recharge_bet_user_pool,
        recharge_win_users=recharge_win_user_pool,
        recharge_profit_users=recharge_profit_user_pool,
        recharge_lose_users=recharge_lose_user_pool
    )
    return dynamic_target_users_dct


def user_pay_ability_report_handler(interval_type, base_time, last_window, event_name, event_rule, index):
    start_time, end_time = get_interval_end_pair(interval_type, base_time, last_window)
    collection = '_'.join(['user', event_name, 'report'])
    recharge_stages = ['NoRecharge', (0, 10), (10, 100), (100, 1000), (1000, 5000),
                       (5000, 10000), (10000, 100000), 'ALL']
    for recharge_stage in recharge_stages:
        if recharge_stage == 'ALL':
            recharge_stage = [None, None]
            _id = '-'.join(['all', str(start_time).split(' ')[0]])
            stage, key = 'all', '汇总'
        elif recharge_stage == 'NoRecharge':
            recharge_stage = [None, 0]
            _id = '-'.join(['0', str(start_time).split(' ')[0]])
            stage, key = 'others', '未充值'
        else:
            _id = '-'.join(['-'.join([str(recharge_stage[0]), str(recharge_stage[1])]), str(start_time).split(' ')[0]])
            stage, key = str(recharge_stage[0]), '-'.join([str(recharge_stage[0]), str(recharge_stage[1])])
        dynamic_target_users_dct = _get_user_pay_ability_report_dynamic_argument_dct(
            index, start_time, end_time, list(recharge_stage)
        )
        report_id = '-'.join(['all', _id, interval_type.value])
        report_template = get_report_template(start_time, interval_type, custom_report_id=report_id)
        report_template.update(
            UserReportCreator.create_user_report(
                start_time=start_time, end_time=end_time, event_rule=event_rule, index=index,
                dynamic_argument_dct=dynamic_target_users_dct
            )
        )
        report_template.update({event_rule.get('group_by').replace('.keyword', ''): 'all', 'key': key,
                                'recharge_stage': stage})
        insert_or_update(report_template, database=index, collection=collection)
        pay_ability_report = UserReportCreator.create_user_report(
            start_time=start_time, end_time=end_time, event_rule=event_rule, index=index,
            dynamic_argument_dct=dynamic_target_users_dct, to_group=True)
        for report in pay_ability_report['list']:
            report_id = '-'.join([report[event_rule.get('group_by').replace('.keyword', '')], _id, interval_type.value])
            report_template = get_report_template(start_time, interval_type, custom_report_id=report_id)
            report_template['key'], report_template['recharge_stage'] = key, stage
            report_template.update(report)
            insert_or_update(report_template, database=index, collection=collection)


def new_user_report_handler(interval_type, base_time, last_window, event_name, event_rule, index):
    start_time, end_time = get_interval_end_pair(interval_type, base_time, last_window)
    user_pool = None
    collection = '_'.join(['user', event_name, 'report'])
    report_template = get_report_template(start_time, interval_type)
    report_template.update(ReportCreator.create_report(user_pool=user_pool, start_time=start_time, end_time=end_time,
                                                       event_rule=event_rule, index=index))
    report_template.update({event_rule.get('group_by').replace('.keyword', ''): 'all'})
    insert_or_update(report_template, database=index, collection=collection)
    new_user_reports = ReportCreator.create_report(user_pool=user_pool, start_time=start_time,
                                                   end_time=end_time, event_rule=event_rule, index=index,
                                                   to_group=True)
    for report in new_user_reports['list']:
        report_id = '-'.join([report[event_rule.get('group_by').replace('.keyword', '')],
                              str(start_time).split(' ')[0], interval_type.value])
        report_template = get_report_template(start_time, interval_type, custom_report_id=report_id)
        report_template.update(report)
        insert_or_update(report_template, database=index, collection=collection)


def _get_new_user_stay_report_dynamic_argument_dct(start_time, end_time, index):
    aggregation_dsl = {
        "query": {
            "bool": {
                "filter": [{"range": {"_event_time": {"gte": start_time.timestamp(), "lt": end_time.timestamp()}}}]
            }
        },
        "size": 0,
        "aggs": {
            "report": {
                "terms": {
                    "field": "_aid.keyword",
                    "size": 10000
                },
                "aggs": {}
            }
        }
    }
    resp_json = es_search_interface(index, aggregation_dsl)
    buckets = resp_json['aggregations']['report']['buckets']
    return {"base_aid_list": [bucket["key"] for bucket in buckets]}


def new_user_stay_report_handler(interval_type, base_time, last_window, event_name, event_rule, index='loki'):
    start_time, end_time = get_interval_end_pair(interval_type, base_time, last_window)
    user_pool = None
    collection = '_'.join(['user', event_name, 'report'])
    dynamic_argument_dct = _get_new_user_stay_report_dynamic_argument_dct(
        start_time, end_time, index
    )
    report_template = get_report_template(start_time, interval_type)
    report_template.update(ReportCreator.create_report(user_pool=user_pool, start_time=start_time, end_time=end_time,
                                                       event_rule=event_rule, index=index,
                                                       dynamic_argument_dct=dynamic_argument_dct))
    insert_or_update(report_template, database=index, collection=collection)


def get_active_user_analysis_report(index, user_id=None, chn_filter_list=None, time_range=None, disable_paginate=None,
                                    registered_time_range=None, sort_by=None, page=None, size=None):
    condition = dict()
    if user_id:
        condition['_user_id'] = user_id
    if chn_filter_list:
        condition['chn'] = {'$in': chn_filter_list}
    condition['day'] = {'$gte': datetime.strftime(time_range[0], "%Y-%m-%d"),
                        '$lte': datetime.strftime(time_range[1], "%Y-%m-%d")}
    condition['registered_at'] = {'$gte': datetime.strftime(registered_time_range[0], '%Y-%m-%d %H:%M:%S'),
                                  '$lte': datetime.strftime(registered_time_range[1], '%Y-%m-%d %H:%M:%S')}
    (collection, event_rule) = ('user_active_user_analysis_report', ACTIVE_USER_ANALYSIS_CONFIG)
    custom_group_by_field = {
        'registered_at': {"$first": '$registered_at'},
        'chn': {"$first": "$chn"},
        '_user_id': {"$first": "$_user_id"}
    }
    analysis_result, total_count = get_report(index, collection, condition, sort_key=sort_by, page=page, size=size,
                                              disable_paginate=disable_paginate, merge_report=True,
                                              event_rule=event_rule, group_key='_user_id',
                                              custom_group_by_field=custom_group_by_field)
    return analysis_result, total_count
